
| ARTeam Beginner Tutorial #5 By: Gabri3l /ARTeam http://cracking.accessroot.com Beginner Tutorial: Inline Patching |
| The Target: Universal Desktop Ruler 2.5.872 |
| The Tools: PEID, Ollydbg 1.10 |
| The Protection: Serial |
Other Information: |
Best viewed in Firefox at 1280x1024
Intro: |
All the tools you will need can be found online: I recommend reading tutorials #3 and #4 before starting this one. I and Shub-Nigurrath have taught you two ways to unpack packed executables. Because of this I will only quickly cover finding the OEP. However, before we begin even working with this executable we will first cover the Registers. If you think you already have a good grasp on x86 registers you can go ahead and skip to Unpacking. |
|
Body: |
|
The Registers: The registers are small areas of memory that programs use to store information. I am sure you have heard that Windows is built on x86 architecture. And that the x86 architecture has 32-bit registers. This means that the registers we are looking at can only hold 32-BITS. A BIT is either a 1 or a 0. So a register can only hold a binary value between 00000000000000000000000000000000 - 11111111111111111111111111111111. That means that a register can hold 4,294,967,295 possible combinations. Okay, Why is it when we see the registers in Olly they only hold 8 characters between 0 and F? Because in Olly, we are used to seeing BYTES. BYTES are eight BITS grouped together. And can hold a value from 0 to 255. However to make it easier, instead of writing 8 BITS every time we want to write a BYTE. We use the Hexadecimal format to write a BYTE. Hexadecimal format is based on the number 16. Now, if you are unfamiliar with the different based number systems pay attention! We use the decimal system which is based on the number 10. That means that whenever we hit the magical increment of 10: we add 1 to the space to the left and start over at zero in the right space. That's all you need to know for Hexadecimal. Just count in increments of the base number. And only add one to the left space when you hit another increment of the base number. Sound confusing? It's not. Example: Start counting from 1 in Hex, 1,2,3,4,5,6,7,8,9,A,B,C,D,E,and F is 15 so 10 is 16. So we count again. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, and hit 1F which is 31. Well we are going to get to another increment of 16 again so add 1 to the left space and start over at zero. 1 + 1 = 2 and start over at zero so we are at 20 in hexadecimal which in decimal is 36. This works for any based number system.
I understand that this is a lot to comprehend but it is good to at least understand hexadecimal the farther along you get in reversing. Okay back to Registers: BYTES are 8 BITS written in hexadecimal. A Register contains 32 BITS which is 4 BYTES. So a register can only hold a value between 00000000 and FFFFFFFF. That's not a lot of room when it comes to memory. Many times the register is broken down into 2 BYTES, and sometimes again into only 1 BYTE.
EAX: Known as the Accumulator Register. This register is probably the most popular register. It is used for general calculations and intel has programmed many special assembly instructions that just use EAX. Functions like LODS, STOS, IN, OUT, INS, OUTS, SCAS, and XLAT are used to specifically move memory in and out of the EAX register. Also API functions almost always return their values through EAX. EDX: Known as the Data Register. This register is traditionally used in conjunction with the EAX register. The EAX register may hold the data to be written and the EDX register may hold the address to write the data to. EDX also often holds the result of mathematical functions. The EDX and EAX registers also can also be used in conjunction to hold 64 bits of information by using EDX:EAX ECX: Known as the Count Register. This register is true to it's name. As it is often used as a counter for LOOP and REP (repeat) functions. It also has assembly functions written specifically for it. Example: JECXZ jumps if the ECX register equals zero. EBX: Known as the Base Register. This register used to be the only register that could be used to hold a memory address for access. Memory access occurs when the register is put between square brackets. Example: MOV EAX, EBX moves the value of EBX into EAX. where MOV EAX, [EBX] moves the value stored at the memory address in EBX into EAX. Now Intel has made it so any register can be used as an address for memory access. So EBX is usually used for general purposes. Hopefully this gives you an idea of the uses of the general purpose registers.We can move on to unpacking this program Unpacking: Let's begin. Open udruler.exe in Olly. You should be here:
Press the Step Over button once Now all we have to do is Press RUN. Wait for the program to be unpacked and we will break on a JMP. Looking at the JMP we see that it jumps to address 004BE9DC. 004E9DC is a completely different part of memory than the one we are in. Maybe it is our OEP! Press Step Into button Looking at the code we see that we are at the beginning of the UDruler executable. (How exactly do I know that this is the beginning? Well, sometimes you aren't 100% sure. But the more experienced you become with unpacking executables you begin to learn what the code at the beginning of a program looks like) Defeating the Protection:
Select line 004A9394 (The Call to UDRULER.004BAFF) and Right-Click. Choose Follow from the menu. By following this call we put ourselves in the routine that checks to see if the program is registered. You should currently be here: This is the beginning of the registration checking function. We want to break here and then follow the code until we see AL being set. Press F2 to set a breakpoint. Now, press Run and UDruler will begin loading. As UDruler appears in your taskbar Olly will break at the breakpoint we just set. We are now inside the Registration Check for this program. Look at the stack and we will find out where we will return from this registration check. In my case the top of the stack says: RETURN to UDRuler.004BEC6E from UDRuler.004BAFF8. This means that when we are done checking if we are registered, the function will return to 0004BEC6E. The program will then test if AL is 0 and continue accordingly. Before we go any further select line 004BAFF8 (where we set out breakpoint) and press F2 again to remove the breakpoint. Now, onto fixing the registration check. To fix this registration check we want to find out where AL is being set. We know that it will probably be one of the last things the function will do before returning to 004BEC6E. Rather then step through all this code we can speed things up by pressing the Execute Till Return button. Go ahead and press it once, give Olly a few seconds and you will break here: Press Step Over to follow the RETN to 004BB330. Continue to press the Step Over button until you reach the next RETN. Looking at the stack again we see that we will RETN to 004BB36D. Press Step Over one more time until you are at 004BB36D: Next there are some POPs. We then reach an instruction that moves the value from EBP into ESP. We know that ESP always points to the top of the stack, so if we move another value into ESP we also change the top of the stack. Look at EBP, in my case the value was 0012FF80. Looking at the stack we see that the line directly below 0012FF80 is the same line we saw when we entered the registration routine. This means that when we hit the RETN we will leave the registration function. This is the code we will need to patch in order to register our program. To change the registration check we want to move a 1 into AL. Select line 004BB36D MOV EAX,EBX and press SPACE to Assemble the line. In the box that comes up type MOV AL,01 and press Assemble. Our code should now look like the following: Well we patched the registration routine to always return registered. So let's test it out. Press RUN and lets see what happens... After the program loads, Right-click on the UDruler tray icon and choose ABOUT. The About box says we are registered! But what about the rest of the program? If you played around with the program before-hand you would have noticed that some of the functions were limited as a trial version. Example: You were not allowed to find the area and perimiter for the whole screen. So right-click the UDruler tray icon and choose Area+Permiter. The program now allows us to measure the whole screen. We have successfully patched the registration check! Creating an Inline Patch: Restart UDruler.exe in Olly. Do not run it, just let it load itself into memory. Now choose VIEW and then Memory from the drop down menu. You should see the following: The .rsrc section starts at 00526000 for me. So I'm going to close the Memory window and in the CPU window Right-Click and Go-To ->Expression. Type in 00526000 and press OK. You should end up here: Now before we begin writing code. We need to know what we are going to write. The instruction to overwrite code is a MOV instruction. We use it in the following way: Okay, remember the addresses and values you wrote down? This is where we use them. We changed the BYTE at ADDRESS 004BB36D to B0. So the first instruction we are going to write is:
MOV BYTE PTR DS:[004BB36D], 0B0. (We add the 0 in front of the B so Olly knows that it is a value and not an instruction) Next, we changed the byte at address 004BB36E into 01. So the second instruction we are going to write is MOV BYTE PTR DS:[004BB36E], 01. The last instruction we want to write is a jump to the OEP. Look back at your notes to find the OEP. In my case, my OEP was 004BE9DC. So the last instruction we write is JMP 004BE9DC. When you are done it should look like this: Now, Select ALL THREE lines you changed and Right-Click. Choose Copy to Executable -> Selection. A new window will open up. In that new window Right-Click and choose Save File. Save the executable as any name you want. The last thing we need to do is change the Jump at the end of the unpacking routine to jump to our code cave. So gp ahead and close UDRuler and Open up the modified executable you just saved. Now we need to go to the end of the packing routine. If you have a good memory you will remember that it is at offset 0052553B. If you don't have a good memory you can Right-Click and Search->Command. Type in JMP 004BE9DC. That will search for the instruction that jumps to our OEP. Either way, you end up at 0052553B. We need to change this jump so instead of jumping to the OEP it jumps to the first instruction of our code cave. In my case the first instruction in my code cave is at address 00528487. (Look at the picture above). To change the line Select it and press SPACE. In the Assemble box type JMP 00528487. Press Assemble. You should see the following: Right-Click and choose Copy to Executable. In the window that opens up Right-Click again and choose Save File. I saved mine as UDFinal.exe. Go ahead and close Olly. The last thing to do is test it out! Double-Click your UDFinal.exe and, if you did everything correctly... It Works!! We learned about the x86 registers. We then applied that knowledge to reversing a registration check. We also learned about code caves and how to find them. Finally we used code caves to create an inline patch for a packed executable. Hopefully with everything you learned you will be able to apply it to other reversing projects. |
|
Conclusion: |
I used this particular program purely as a demonstration for creating an inline patch. If like the program and are going to use it please purchase it. Thanks to the whole ARTeam: Thanks to all the people who take time to write tutorials. If you have any suggestions, comments or corrections email me: Gabri3l2003[at]yahoo.com |